#include "power_save_timer.h"
#include "application.h"

#include <esp_log.h>

/**
 * @brief 电源节能定时器日志标签
 */
#define TAG "PowerSaveTimer"


/**
 * @brief 电源节能定时器构造函数
 * 
 * @param cpu_max_freq CPU最大频率
 * @param seconds_to_sleep 进入睡眠模式前的空闲秒数
 * @param seconds_to_shutdown 关机前的空闲秒数
 */
PowerSaveTimer::PowerSaveTimer(int cpu_max_freq, int seconds_to_sleep, int seconds_to_shutdown)
    : cpu_max_freq_(cpu_max_freq), seconds_to_sleep_(seconds_to_sleep), seconds_to_shutdown_(seconds_to_shutdown) {
    // 创建定时器配置
    esp_timer_create_args_t timer_args = {
        .callback = [](void* arg) {
            auto self = static_cast<PowerSaveTimer*>(arg);
            self->PowerSaveCheck();
        },
        .arg = this,
        .dispatch_method = ESP_TIMER_TASK,
        .name = "power_save_timer",
        .skip_unhandled_events = true,
    };
    ESP_ERROR_CHECK(esp_timer_create(&timer_args, &power_save_timer_));
}

/**
 * @brief 电源节能定时器析构函数
 * 
 * 停止并删除定时器
 */
PowerSaveTimer::~PowerSaveTimer() {
    esp_timer_stop(power_save_timer_);
    esp_timer_delete(power_save_timer_);
}

/**
 * @brief 设置电源节能模式是否启用
 * 
 * @param enabled 是否启用电源节能模式
 */
void PowerSaveTimer::SetEnabled(bool enabled) {
    if (enabled && !enabled_) {
        // 启用电源节能模式
        ticks_ = 0;
        enabled_ = enabled;
        ESP_ERROR_CHECK(esp_timer_start_periodic(power_save_timer_, 1000000));
        ESP_LOGI(TAG, "Power save timer enabled");
    } else if (!enabled && enabled_) {
        // 禁用电源节能模式
        ESP_ERROR_CHECK(esp_timer_stop(power_save_timer_));
        enabled_ = enabled;
        WakeUp();
        ESP_LOGI(TAG, "Power save timer disabled");
    }
}

/**
 * @brief 设置进入睡眠模式时的回调函数
 * 
 * @param callback 进入睡眠模式时执行的回调函数
 */
void PowerSaveTimer::OnEnterSleepMode(std::function<void()> callback) {
    on_enter_sleep_mode_ = callback;
}

/**
 * @brief 设置退出睡眠模式时的回调函数
 * 
 * @param callback 退出睡眠模式时执行的回调函数
 */
void PowerSaveTimer::OnExitSleepMode(std::function<void()> callback) {
    on_exit_sleep_mode_ = callback;
}

/**
 * @brief 设置关机请求时的回调函数
 * 
 * @param callback 关机请求时执行的回调函数
 */
void PowerSaveTimer::OnShutdownRequest(std::function<void()> callback) {
    on_shutdown_request_ = callback;
}

/**
 * @brief 电源节能检查
 * 
 * 定时检查是否需要进入睡眠模式或关机
 */
void PowerSaveTimer::PowerSaveCheck() {
    auto& app = Application::GetInstance();
    // 如果不在睡眠模式且应用不能进入睡眠模式，重置计时器
    if (!in_sleep_mode_ && !app.CanEnterSleepMode()) {
        ticks_ = 0;
        return;
    }

    ticks_++;
    // 检查是否达到进入睡眠模式的时间
    if (seconds_to_sleep_ != -1 && ticks_ >= seconds_to_sleep_) {
        if (!in_sleep_mode_) {
            // 进入睡眠模式
            in_sleep_mode_ = true;
            if (on_enter_sleep_mode_) {
                on_enter_sleep_mode_();
            }

            // 配置CPU频率和轻度睡眠
            if (cpu_max_freq_ != -1) {
                esp_pm_config_t pm_config = {
                    .max_freq_mhz = cpu_max_freq_,
                    .min_freq_mhz = 40,
                    .light_sleep_enable = true,
                };
                esp_pm_configure(&pm_config);
            }
        }
    }
    // 检查是否达到关机时间
    if (seconds_to_shutdown_ != -1 && ticks_ >= seconds_to_shutdown_ && on_shutdown_request_) {
        on_shutdown_request_();
    }
}

/**
 * @brief 唤醒设备
 * 
 * 从睡眠模式中唤醒设备，恢复正常工作状态
 */
void PowerSaveTimer::WakeUp() {
    ticks_ = 0;
    if (in_sleep_mode_) {
        // 退出睡眠模式
        in_sleep_mode_ = false;

        // 恢复CPU频率配置
        if (cpu_max_freq_ != -1) {
            esp_pm_config_t pm_config = {
                .max_freq_mhz = cpu_max_freq_,
                .min_freq_mhz = cpu_max_freq_,
                .light_sleep_enable = false,
            };
            esp_pm_configure(&pm_config);
        }

        // 执行退出睡眠模式的回调
        if (on_exit_sleep_mode_) {
            on_exit_sleep_mode_();
        }
    }
}
